package com.bjb.vr.operation.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bjb.vr.common.ao.StatisticAo;
import com.bjb.vr.common.constant.ThreadLocalConstant;
import com.bjb.vr.common.dto.ResDictionary;
import com.bjb.vr.common.dto.ResPlatformResource;
import com.bjb.vr.common.dto.SysTenant;
import com.bjb.vr.common.mapper.DevicesStatisticsMapper;
import com.bjb.vr.common.mapper.ResPlatformResourceMapper;
import com.bjb.vr.common.utils.DateTimeUtil;
import com.bjb.vr.common.utils.ThreadLocalUtil;
import com.bjb.vr.common.vo.StatisticVo;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @description:
 * @author: HuJingBo
 * @time: 2022/11/30 12:47
 */
@Service
public class SysStatisticsService {

    @Resource
    private DevicesStatisticsMapper devicesStatisticsMapper;

    @Resource
    private ResPlatformResourceMapper platformResourceMapper;

    /**
     * 获取设备统计数据
     *
     * @return
     */
    public JSONArray devicesCount(StatisticAo statisticAo) {
        ThreadLocalUtil.set(ThreadLocalConstant.NO_TENANT_ID_VERIFY, true);
        HashMap<String, Integer> countDevicesStatus = devicesStatisticsMapper.devicesStatusCountOpt(statisticAo.getTenantId());
        HashMap<String, BigDecimal> countDevicesUseTimeOfDay = devicesStatisticsMapper.devicesUseTimeCountOpt(statisticAo.getTenantId(), DateTimeUtil.nowStrTime(DateTimeUtil.DATE_FORMAT_DAY), DateTimeUtil.nowStrTime(DateTimeUtil.DATE_FORMAT_DAY));
        HashMap<String, BigDecimal> countDevicesUseTimeOfWeek = devicesStatisticsMapper.devicesUseTimeCountOpt(statisticAo.getTenantId(), DateTimeUtil.firstDayOfWeek(), DateTimeUtil.lastDayOfWeek());
        HashMap<String, BigDecimal> countDevicesUseTimeOfMonth = devicesStatisticsMapper.devicesUseTimeCountOpt(statisticAo.getTenantId(), DateTimeUtil.firstDayOfMonth(), DateTimeUtil.lastDayOfMonth());
        HashMap<String, BigDecimal> countDevicesUseTimeOfTotal = devicesStatisticsMapper.countDevicesUseTimeOfTotal(statisticAo.getTenantId());

        // 设备状态统计
        HashMap statusMap = new HashMap();
        JSONArray statusArray = new JSONArray();
        for (Map.Entry<String, Integer> entry : countDevicesStatus.entrySet()) {
            JSONObject object = new JSONObject();
            object.put("name", entry.getKey());
            object.put("value", entry.getValue());
            statusArray.add(object);
        }

        statusMap.put("text", "设备状态统计");
        statusMap.put("status", statusArray);

        // 设备使用时长统计
        HashMap useTimeMap = new HashMap();
        JSONArray useTimeArray = new JSONArray();

        JSONObject object1 = new JSONObject();
        object1.put("name", "day");
        object1.put("value", countDevicesUseTimeOfDay.get("avgUseTime"));
        useTimeArray.add(object1);

        JSONObject object2 = new JSONObject();
        object2.put("name", "week");
        object2.put("value", countDevicesUseTimeOfWeek.get("avgUseTime"));
        useTimeArray.add(object2);

        JSONObject object3 = new JSONObject();
        object3.put("name", "month");
        object3.put("value", countDevicesUseTimeOfMonth.get("avgUseTime"));
        useTimeArray.add(object3);

        JSONObject object4 = new JSONObject();
        object4.put("name", "total");
        object4.put("value", countDevicesUseTimeOfTotal.get("totalUseTime"));
        useTimeArray.add(object4);

        useTimeMap.put("text", "设备使用时长统计");
        useTimeMap.put("useTime", useTimeArray);

        // 信息汇总
        JSONArray jsonArray = new JSONArray();
        jsonArray.add(statusMap);
        jsonArray.add(useTimeMap);
        return jsonArray;
    }

    /**
     * 获取资源统计数据
     *
     * @return
     */
    public JSONArray resourcesCountEdu(StatisticAo statisticAo) {
        ThreadLocalUtil.set(ThreadLocalConstant.NO_TENANT_ID_VERIFY, true);
        HashMap<String, Integer> countByPeriod = null;
        HashMap<String, Integer> countByLevel = null;
        HashMap<String, Integer> countBySubject = null;
        // 查询所有
        if (StringUtils.isBlank(statisticAo.getPeriod())){
            countByPeriod = devicesStatisticsMapper.resourcesCountByPrimaryAndMiddle();
            countByLevel = devicesStatisticsMapper.resourcesCountByPrimaryAndMiddleAndLevel();
            countBySubject = new HashMap<>();
        }else {
            // 按照学段查询
            if (statisticAo.getPeriod().equals("小学")) {
                countByPeriod = devicesStatisticsMapper.resourcesCountByPrimary(statisticAo.getTenantId(), statisticAo.getPeriod());
                countByLevel = devicesStatisticsMapper.resourcesCountByPrimaryAndLevel(statisticAo.getTenantId());
                countBySubject = devicesStatisticsMapper.resourcesCountByPrimaryAndSubject(statisticAo.getTenantId(), statisticAo.getPeriod());
            } else if (statisticAo.getPeriod().equals("初中")) {
                countByPeriod = devicesStatisticsMapper.resourcesCountByMiddle(statisticAo.getTenantId(), statisticAo.getPeriod());
                countByLevel = devicesStatisticsMapper.resourcesCountByMiddleAndLevel(statisticAo.getTenantId());
                countBySubject = devicesStatisticsMapper.resourcesCountByMiddleAndSubject(statisticAo.getTenantId(), statisticAo.getPeriod());
            }
        }

        // 课程学段分类
        HashMap periodMap = new HashMap();
        JSONArray periodArray = new JSONArray();
        if (Objects.nonNull(countByPeriod)) {
            for (Map.Entry<String, Integer> entry : countByPeriod.entrySet()) {
                JSONObject object = new JSONObject();
                object.put("name", entry.getKey());
                object.put("value", entry.getValue());
                periodArray.add(object);
            }
        }
        periodMap.put("text", "课程学段分类");
        periodMap.put("level", periodArray);

        // 课程年级分类
        HashMap levelMap = new HashMap();
        JSONArray levelArray = new JSONArray();
        if (Objects.nonNull(countByLevel)) {
            for (Map.Entry<String, Integer> entry : countByLevel.entrySet()) {
                JSONObject object = new JSONObject();
                object.put("name", entry.getKey());
                object.put("value", entry.getValue());
                levelArray.add(object);
            }
        }
        levelMap.put("text", "课程年级分类");
        levelMap.put("level", levelArray);

        // 课程学科分类
        HashMap subjectMap = new HashMap();
        JSONArray subjectArray = new JSONArray();
        if (Objects.nonNull(countBySubject)) {
            for (Map.Entry<String, Integer> entry : countBySubject.entrySet()) {
                JSONObject object = new JSONObject();
                object.put("name", entry.getKey());
                object.put("value", entry.getValue());
                subjectArray.add(object);
            }
        }
        subjectMap.put("text", "课程学科分类");
        subjectMap.put("subject", subjectArray);

        // 信息汇总
        JSONArray jsonArray = new JSONArray();
        jsonArray.add(periodMap);
        jsonArray.add(levelMap);
        jsonArray.add(subjectMap);
        return jsonArray;
    }

    /**
     * 获取资源统计数据
     *
     * @return
     */
    public JSONArray resourcesCountParty(StatisticAo statisticAo) {
        ThreadLocalUtil.set(ThreadLocalConstant.NO_TENANT_ID_VERIFY, true);
        HashMap<String, Integer> countByParty = devicesStatisticsMapper.resourcesCountParty(statisticAo.getTenantId());

        // 课程学科分类
        HashMap partyMap = new HashMap();
        JSONArray partyArray = new JSONArray();
        if (Objects.nonNull(countByParty)) {
            for (Map.Entry<String, Integer> entry : countByParty.entrySet()) {
                JSONObject object = new JSONObject();
                object.put("name", entry.getKey());
                object.put("value", entry.getValue());
                partyArray.add(object);
            }
        }
        partyMap.put("text", "课程类型分类");
        partyMap.put("subject", partyArray);

        // 信息汇总
        JSONArray jsonArray = new JSONArray();
        jsonArray.add(partyMap);
        return jsonArray;
    }

    /**
     * 课程资源详情--客户使用数据
     *
     * @param statisticAo
     * @return
     */
    public IPage<StatisticVo> resourcesDetail(StatisticAo statisticAo) {
        ThreadLocalUtil.set(ThreadLocalConstant.NO_TENANT_ID_VERIFY, true);
        MPJLambdaWrapper<StatisticVo> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper.select(ResPlatformResource::getId)
                .select(ResPlatformResource::getTenantId)
                .select(SysTenant::getTenantName)
                .select(ResPlatformResource::getResName)
                .select(ResPlatformResource::getResType)
                .selectAs(ResDictionary::getDictName, "themeName")
                .select(ResPlatformResource::getPeriod)
                .select(ResPlatformResource::getLevel)
                .select(ResPlatformResource::getSubject)
                .select(ResPlatformResource::getUseCount)
                .leftJoin(SysTenant.class, SysTenant::getTenantId, ResPlatformResource::getTenantId)
                .leftJoin(ResDictionary.class, ResDictionary::getDictCode, ResPlatformResource::getThemeCode);

        // 查询条件
        queryWrapper.eq(StringUtils.isNotBlank(statisticAo.getTenantId()), ResPlatformResource::getTenantId, statisticAo.getTenantId());
        queryWrapper.like(StringUtils.isNotBlank(statisticAo.getResName()), ResPlatformResource::getResName, statisticAo.getResName());
        queryWrapper.eq(StringUtils.isNotBlank(statisticAo.getThemeCode()), ResPlatformResource::getThemeCode, statisticAo.getThemeCode());
        queryWrapper.eq(StringUtils.isNotBlank(statisticAo.getPeriod()), ResPlatformResource::getPeriod, statisticAo.getPeriod());
        queryWrapper.eq(StringUtils.isNotBlank(statisticAo.getLevel()), ResPlatformResource::getLevel, statisticAo.getLevel());
        queryWrapper.eq(StringUtils.isNotBlank(statisticAo.getSubject()), ResPlatformResource::getSubject, statisticAo.getSubject());
        IPage<StatisticVo> selectJoinPage = platformResourceMapper.selectJoinPage(new Page<>(statisticAo.getCurrent(), statisticAo.getSize()), StatisticVo.class, queryWrapper);
        return selectJoinPage;
    }

    /**
     * 课程资源详情--课程资源使用数据
     *
     * @param statisticAo
     * @return
     */
    public IPage<StatisticVo> resourcesDataDetail(StatisticAo statisticAo) {
        ThreadLocalUtil.set(ThreadLocalConstant.NO_TENANT_ID_VERIFY, true);
        MPJLambdaWrapper<StatisticVo> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper.select(ResPlatformResource::getId)
                .selectSum(ResPlatformResource::getUseCount,"useCount")
                .select(ResPlatformResource::getResName)
                .select(ResPlatformResource::getPeriod)
                .select(ResPlatformResource::getLevel)
                .select(ResPlatformResource::getSubject);
        queryWrapper.groupBy(ResPlatformResource::getResName);

        // 查询条件
        queryWrapper.like(StringUtils.isNotBlank(statisticAo.getResName()), ResPlatformResource::getResName, statisticAo.getResName());
        queryWrapper.eq(StringUtils.isNotBlank(statisticAo.getPeriod()), ResPlatformResource::getPeriod, statisticAo.getPeriod());
        queryWrapper.eq(StringUtils.isNotBlank(statisticAo.getLevel()), ResPlatformResource::getLevel, statisticAo.getLevel());
        queryWrapper.eq(StringUtils.isNotBlank(statisticAo.getSubject()), ResPlatformResource::getSubject, statisticAo.getSubject());
        IPage<StatisticVo> selectJoinPage = platformResourceMapper.selectJoinPage(new Page<>(statisticAo.getCurrent(), statisticAo.getSize()), StatisticVo.class, queryWrapper);
        return selectJoinPage;
    }

    /**
     * 课程资源总计使用次数
     *
     * @param statisticAo
     * @return
     */
    public Integer resourcesTotalCount(StatisticAo statisticAo) {
        ThreadLocalUtil.set(ThreadLocalConstant.NO_TENANT_ID_VERIFY, true);
        MPJLambdaWrapper<StatisticVo> queryWrapper = new MPJLambdaWrapper<>();
        queryWrapper.selectSum(ResPlatformResource::getUseCount, "totalUseCount");
        // 查询条件
        queryWrapper.eq(StringUtils.isNotBlank(statisticAo.getTenantId()), ResPlatformResource::getTenantId, statisticAo.getTenantId());
        queryWrapper.like(StringUtils.isNotBlank(statisticAo.getResName()), ResPlatformResource::getResName, statisticAo.getResName());
        queryWrapper.eq(StringUtils.isNotBlank(statisticAo.getThemeCode()), ResPlatformResource::getThemeCode, statisticAo.getThemeCode());
        Map<String, Object> objectMap = platformResourceMapper.selectJoinMap(queryWrapper);
        if (objectMap == null || objectMap.size() == 0) {
            return 0;
        }
        return Integer.parseInt(objectMap.get("totalUseCount").toString());
    }

    /**
     * 统计在线离线设备--根据条件
     *
     * @param statisticAo
     * @return
     */
    public JSONArray devicesCountByCondition(StatisticAo statisticAo) {
        ThreadLocalUtil.set(ThreadLocalConstant.NO_TENANT_ID_VERIFY, true);
        HashMap<String, Integer> countDevicesStatus = devicesStatisticsMapper.devicesStatusCountOpt(statisticAo.getTenantId());
        HashMap<String, BigDecimal> countDevicesUseTimeOfTotal = devicesStatisticsMapper.countDevicesUseTimeOfTotal(statisticAo.getTenantId());

        // 设备状态统计
        HashMap statusMap = new HashMap();
        JSONArray statusArray = new JSONArray();
        for (Map.Entry<String, Integer> entry : countDevicesStatus.entrySet()) {
            JSONObject object = new JSONObject();
            object.put("name", entry.getKey());
            object.put("value", entry.getValue());
            statusArray.add(object);
        }

        // 设备使用时长统计
        HashMap userTimeMap = new HashMap();
        userTimeMap.put("name", "userTime");
        userTimeMap.put("value", countDevicesUseTimeOfTotal.get("totalUseTime"));
        statusArray.add(userTimeMap);

        return statusArray;
    }
}
